use std::sync::Arc;

use axum::{extract::State, routing::post, Json, Router};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tracing::info;

use crate::{config::ApplicationConfig, manager::ManagerLock, response::Res, APPLICATION_CONTEXT};

#[derive(Deserialize)]
pub struct GetHardwareBySerial {
    serial: String,
}

#[derive(Serialize, Deserialize)]
pub struct ReportLossArgs {
    serial: String,
    status: String,
    #[serde(rename = "applyType")]
    apply_type: u32,
    #[serde(rename = "callUserName")]
    call_user_name: String,
    tel: String,
    description: String,
    code: String,
    extend1: u32,
}

#[derive(Deserialize)]
pub struct SmsCodeArgs {
    tel: String,
}

#[derive(Serialize, Deserialize)]
pub struct KefuArgs {
    serial: String,
    status: String,
    #[serde(rename = "callUserName")]
    call_user_name: String,
    tel: String,
    description: String,
    code: String,
}
/// 根据序列号查询硬件信息
pub async fn get_hardware_by_serial(
    State(manager): State<Arc<ManagerLock>>,
    Json(GetHardwareBySerial { serial }): Json<GetHardwareBySerial>,
) -> Res<Value> {
    let token = match manager.get_token() {
        Some(t) => t,
        None => return Res::error("获取token失败".to_string()),
    };
    let config = APPLICATION_CONTEXT.get::<ApplicationConfig>();
    let url = format!(
        "{}/api/hardware-resources/1/hardwareLockAgency/clientQueryHardwareLockBySerial/{}",
        config.base_url(),
        serial
    );
    let client = reqwest::Client::new();

    match client
        .get(&url)
        .header("Content-Type", "application/json")
        .header("Authorization", format!("bearer {}", token))
        .header("Product_code", "AGENCY_ADMIN")
        .send()
        .await
    {
        Ok(res) => {
            if res.status() == 200 {
                match res.json::<Value>().await {
                    Ok(value) => {
                        return Res::success(value["result"].clone());
                    }
                    Err(e) => Res::error(format!("解析响应失败: {}", e)),
                }
            } else {
                Res::error(format!("请求失败: {}", res.status()))
            }
        }
        Err(e) => Res::error(format!("网络错误，请稍后重试: {}", e)),
    }
}

/// 客户报失
pub async fn client_report_loss(
    State(manager): State<Arc<ManagerLock>>,
    Json(args): Json<ReportLossArgs>,
) -> Res<Value> {
    let token = match manager.get_token() {
        Some(t) => t,
        None => return Res::error("获取token失败".to_string()),
    };
    let config = APPLICATION_CONTEXT.get::<ApplicationConfig>();
    let url = format!(
        "{}/api/hardware-resources/1/hardwareLockAgency/clientReportLoss",
        config.base_url()
    );
    let client = reqwest::Client::new();

    match client
        .post(&url)
        .header("Content-Type", "application/json")
        .header("Authorization", format!("bearer {}", token))
        .header("Product_code", "AGENCY_ADMIN")
        .json(&args)
        .send()
        .await
    {
        Ok(res) => {
            if res.status() == 200 {
                match res.json::<Value>().await {
                    Ok(value) => Res::success(value),
                    Err(e) => Res::error(format!("解析响应失败: {}", e)),
                }
            } else {
                Res::error(format!("请求失败: {}", res.status()))
            }
        }
        Err(e) => Res::error(format!("网络错误，请稍后重试: {}", e)),
    }
}

/// 客户取消报失
pub async fn client_cancel_report_loss(
    State(manager): State<Arc<ManagerLock>>,
    Json(args): Json<ReportLossArgs>,
) -> Res<Value> {
    let token = match manager.get_token() {
        Some(t) => t,
        None => return Res::error("获取token失败".to_string()),
    };
    let config = APPLICATION_CONTEXT.get::<ApplicationConfig>();
    let url = format!(
        "{}/api/hardware-resources/1/hardwareLockAgency/clientCancelReportLoss",
        config.base_url()
    );
    let client = reqwest::Client::new();

    match client
        .post(&url)
        .header("Content-Type", "application/json")
        .header("Authorization", format!("bearer {}", token))
        .header("Product_code", "AGENCY_ADMIN")
        .json(&args)
        .send()
        .await
    {
        Ok(res) => {
            if res.status() == 200 {
                match res.json::<Value>().await {
                    Ok(value) => Res::success(value),
                    Err(e) => Res::error(format!("解析响应失败: {}", e)),
                }
            } else {
                Res::error(format!("请求失败: {}", res.status()))
            }
        }
        Err(e) => Res::error(format!("网络错误，请稍后重试: {}", e)),
    }
}

/// 获取短信验证码
pub async fn sms_code(
    State(manager): State<Arc<ManagerLock>>,
    Json(args): Json<SmsCodeArgs>,
) -> Res<Value> {
    if args.tel.is_empty() {
        return Res::error("tel参数不存在".to_string());
    }
    let config = APPLICATION_CONTEXT.get::<ApplicationConfig>();
    let url = format!(
        "{}/api/auth-resource/1/{}/smsCodeForClient",
        config.base_url(),
        args.tel
    );
    let client = reqwest::Client::new();

    match client
        .get(&url)
        .header("Content-Type", "application/json")
        .header("Application_name", "PORTAL")
        .header("Product_code", "AGENCY_ADMIN")
        .send()
        .await
    {
        Ok(res) => {
            if res.status() == 200 {
                match res.json::<Value>().await {
                    Ok(value) => Res::success(value),
                    Err(e) => Res::error(format!("解析响应失败: {}", e)),
                }
            } else {
                Res::error(format!("请求失败: {}", res.status()))
            }
        }
        Err(e) => Res::error(format!("网络错误，请稍后重试: {}", e)),
    }
}

/// 客服添加
pub async fn kefu(
    State(manager): State<Arc<ManagerLock>>,
    Json(args): Json<KefuArgs>,
) -> Res<Value> {
    let token = match manager.get_token() {
        Some(t) => t,
        None => return Res::error("获取token失败".to_string()),
    };
    let config = APPLICATION_CONTEXT.get::<ApplicationConfig>();
    let url = format!(
        "{}/api/hardware-resources/1/hardware/hardwarekefu/add",
        config.base_url()
    );
    let client = reqwest::Client::new();

    match client
        .post(&url)
        .header("Content-Type", "application/json")
        .header("Authorization", format!("bearer {}", token))
        .header("Product_code", "AGENCY_ADMIN")
        .json(&args)
        .send()
        .await
    {
        Ok(res) => {
            if res.status() == 200 {
                match res.json::<Value>().await {
                    Ok(value) => Res::success(value),
                    Err(e) => Res::error(format!("解析响应失败: {}", e)),
                }
            } else {
                Res::error(format!("请求失败: {}", res.status()))
            }
        }
        Err(e) => Res::error(format!("网络错误，请稍后重试: {}", e)),
    }
}

pub fn router() -> Router<Arc<ManagerLock>> {
    Router::new()
        .route("/clientReportLoss", post(client_report_loss))
        .route("/clientCancelReportLoss", post(client_cancel_report_loss))
        .route("/smsCode", post(sms_code))
        .route("/kefu", post(kefu))
        .route("/getHardwareBySerial", post(get_hardware_by_serial))
}
